"use client";

import { useEffect, useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { db, storage } from "@/lib/firebase/clientApp";
import { addDoc, collection, deleteDoc, doc, getDoc, onSnapshot, query, serverTimestamp, updateDoc, where } from "firebase/firestore";
import { getDownloadURL, ref, uploadBytes } from "firebase/storage";

type SongDoc = {
  id: string;
  title?: string;
  name?: string;
};

export default function UserDetailClient({ id }: { id: string }) {
  const router = useRouter();
  const [userName, setUserName] = useState<string>("");
  const [songs, setSongs] = useState<SongDoc[]>([]);
  const [clipId, setClipId] = useState<string>("");
  const [existingSongId, setExistingSongId] = useState<string>("");
  const [isImporting, setIsImporting] = useState<boolean>(false);
  const [importError, setImportError] = useState<string | null>(null);

  // Metadata form state
  const [bio, setBio] = useState<string>("");
  const [tags, setTags] = useState<string>("");
  const [avatarFile, setAvatarFile] = useState<File | null>(null);
  const [coverFile, setCoverFile] = useState<File | null>(null);
  const [currentAvatarURL, setCurrentAvatarURL] = useState<string>("");
  const [currentCoverURL, setCurrentCoverURL] = useState<string>("");
  const [isSavingMeta, setIsSavingMeta] = useState<boolean>(false);
  const [metaError, setMetaError] = useState<string | null>(null);

  // Song rename state
  const [editingSongId, setEditingSongId] = useState<string | null>(null);
  const [editingSongName, setEditingSongName] = useState<string>("");
  const [isSavingRename, setIsSavingRename] = useState<boolean>(false);
  const [renameError, setRenameError] = useState<string | null>(null);

  // Delete state
  const [deletingSongId, setDeletingSongId] = useState<string | null>(null);
  const [isDeletingUser, setIsDeletingUser] = useState<boolean>(false);
  const [deleteUserError, setDeleteUserError] = useState<string | null>(null);

  const userRef = useMemo(() => doc(db, "user", id), [id]);

  useEffect(() => {
    async function loadUser() {
      const snap = await getDoc(userRef);
      const dn = (snap.data()?.displayName as string) || "";
      setUserName(dn);
      const data = snap.data() as Record<string, unknown> | undefined;
      if (data) {
        setBio((data.bio as string) || "");
        setTags((data.tags as string) || "");
        setCurrentAvatarURL((data.avatarURL as string) || "");
        setCurrentCoverURL((data.coverURL as string) || "");
      }
    }
    loadUser();
  }, [userRef]);

  useEffect(() => {
    const q = query(collection(db, "song"), where("createdBy", "==", userRef));
    const unsub = onSnapshot(q, (snapshot) => {
      const items: SongDoc[] = snapshot.docs.map((d) => {
        const data = d.data() as { title?: string; name?: string };
        return { id: d.id, title: data?.title, name: data?.name };
      });
      setSongs(items);
    });
    return () => unsub();
  }, [userRef]);

  async function handleImport(e: React.FormEvent) {
    e.preventDefault();
    setImportError(null);
    const idTrimmed = clipId.trim();
    const existingSongIdTrimmed = existingSongId.trim();
    if (!idTrimmed) {
      setImportError("Clip ID is required.");
      return;
    }
    try {
      setIsImporting(true);
      const res = await fetch(`/api/suno/clip/${encodeURIComponent(idTrimmed)}`);
      if (!res.ok) {
        throw new Error(`Upstream error: ${res.status}`);
      }
      const data = await res.json();
      const songName = (data?.title as string) || (data?.name as string) || "";
      const lyrics = (data?.metadata?.prompt as string) || "";
      const lyricsParts = lyrics.split("---");
      const lyricsText = lyricsParts[1]?.trim() || "";
      if (existingSongIdTrimmed) {
        // Update existing song document with imported Suno data
        const targetRef = doc(db, "song", existingSongIdTrimmed);
        const snap = await getDoc(targetRef);
        if (!snap.exists()) {
          throw new Error("Song ID not found.");
        }
        const createdByRef = (snap.data() as any)?.createdBy;
        if (createdByRef?.id && createdByRef.id !== id) {
          throw new Error("Song does not belong to this user.");
        }
        await updateDoc(targetRef, {
          sunoClipId: idTrimmed,
          name: songName,
          audioURL: data?.audio_url as string,
          imageURL: data?.image_large_url as string,
          lyrics: lyricsText,
          isUpload: true,
        });
      } else {
        // Create a new song document with imported Suno data
        await addDoc(collection(db, "song"), {
          createdBy: userRef,
          sunoClipId: idTrimmed,
          name: songName,
          audioURL: data?.audio_url as string,
          imageURL: data?.image_large_url as string,
          lyrics: lyricsText,
          isUpload: true,
          createdAt: serverTimestamp(),
        });
      }
      setClipId("");
      setExistingSongId("");
    } catch (err) {
      const message = err instanceof Error ? err.message : null;
      setImportError(message || "Failed to import clip. Please verify the ID and try again.");
    } finally {
      setIsImporting(false);
    }
  }

  function getFileExtension(fileName: string): string {
    const idx = fileName.lastIndexOf(".");
    return idx >= 0 ? fileName.substring(idx + 1) : "";
  }

  async function uploadIfPresent(path: string, file: File | null): Promise<{ path?: string; url?: string }> {
    if (!file) return {};
    const storageRef = ref(storage, path);
    await uploadBytes(storageRef, file);
    const url = await getDownloadURL(storageRef);
    return { path, url };
  }

  async function handleSaveMetadata(e: React.FormEvent) {
    e.preventDefault();
    setMetaError(null);
    try {
      setIsSavingMeta(true);
      const updates: Record<string, unknown> = {
        bio: bio ?? "",
        tags: tags ?? "",
      };

      if (avatarFile) {
        const ext = getFileExtension(avatarFile.name) || "jpg";
        const avatarPath = `users/${id}/avatar_${Date.now()}.${ext}`;
        const avatar = await uploadIfPresent(avatarPath, avatarFile);
        if (avatar.path) updates.avatarPath = avatar.path;
        if (avatar.url) updates.avatarURL = avatar.url;
        if (avatar.url) setCurrentAvatarURL(avatar.url);
      }

      if (coverFile) {
        const ext = getFileExtension(coverFile.name) || "jpg";
        const coverPath = `users/${id}/cover_${Date.now()}.${ext}`;
        const cover = await uploadIfPresent(coverPath, coverFile);
        if (cover.path) updates.coverPath = cover.path;
        if (cover.url) updates.coverURL = cover.url;
        if (cover.url) setCurrentCoverURL(cover.url);
      }

      await updateDoc(userRef, updates);
      setAvatarFile(null);
      setCoverFile(null);
    } catch (err) {
      setMetaError("Failed to save metadata. Please try again.");
    } finally {
      setIsSavingMeta(false);
    }
  }

  function startEditingSong(song: SongDoc) {
    setRenameError(null);
    setEditingSongId(song.id);
    setEditingSongName((song.title || song.name || "").toString());
  }

  function cancelEditingSong() {
    setRenameError(null);
    setEditingSongId(null);
    setEditingSongName("");
  }

  async function saveSongName() {
    if (!editingSongId) return;
    const trimmed = editingSongName.trim();
    if (!trimmed) {
      setRenameError("Name is required.");
      return;
    }
    try {
      setIsSavingRename(true);
      setRenameError(null);
      // Update both name and title for compatibility with existing data
      await updateDoc(doc(db, "song", editingSongId), { name: trimmed, title: trimmed });
      setEditingSongId(null);
      setEditingSongName("");
    } catch (err) {
      setRenameError("Failed to rename song. Please try again.");
    } finally {
      setIsSavingRename(false);
    }
  }

  async function handleDeleteSong(songId: string) {
    const confirmed = typeof window !== "undefined" ? window.confirm("Delete this song permanently?") : true;
    if (!confirmed) return;
    try {
      setDeletingSongId(songId);
      await deleteDoc(doc(db, "song", songId));
      // onSnapshot will update the table automatically
    } catch (err) {
      // no-op UI error; could expand to per-row error if needed
    } finally {
      setDeletingSongId(null);
    }
  }

  async function handleDeleteUser() {
    const confirmed = typeof window !== "undefined" ? window.confirm("Delete this user document permanently? This cannot be undone.") : true;
    if (!confirmed) return;
    try {
      setDeleteUserError(null);
      setIsDeletingUser(true);
      await deleteDoc(userRef);
      router.push("/");
    } catch (err) {
      setDeleteUserError("Failed to delete user. Please try again.");
    } finally {
      setIsDeletingUser(false);
    }
  }

  return (
    <div className="flex min-h-screen items-start justify-center bg-zinc-50 font-sans dark:bg-black">
      <main className="flex w-full max-w-3xl flex-col gap-8 py-16 px-6 sm:px-8">
        <div>
          <Link href="/" className="text-sm text-blue-600 hover:underline dark:text-blue-400">← Back</Link>
        </div>
        <section className="rounded-xl border border-black/10 bg-white p-6 shadow-sm dark:border-white/10 dark:bg-black">
          <div className="flex items-center justify-between gap-3">
            <h1 className="text-2xl font-semibold text-black dark:text-zinc-50">
              {userName ? userName : "User"}’s Songs
            </h1>
            <div className="flex items-center gap-2">
              <button
                type="button"
                onClick={handleDeleteUser}
                disabled={isDeletingUser}
                className="h-[36px] rounded-md bg-red-600 px-3 text-white transition-opacity disabled:opacity-50"
              >
                {isDeletingUser ? "Deleting..." : "Delete User"}
              </button>
            </div>
          </div>
          {deleteUserError && <p className="mt-3 text-sm text-red-600 dark:text-red-400">{deleteUserError}</p>}
        </section>

        <section className="rounded-xl border border-black/10 bg-white p-6 shadow-sm dark:border-white/10 dark:bg-black">
          <h2 className="mb-4 text-xl font-semibold text-black dark:text-zinc-50">Import from Suno</h2>
          <form onSubmit={handleImport} className="flex flex-col gap-4 sm:flex-row sm:items-end">
            <div className="flex-1">
              <label htmlFor="clipId" className="mb-1 block text-sm font-medium text-zinc-700 dark:text-zinc-300">
                Suno Clip ID
              </label>
              <input
                id="clipId"
                name="clipId"
                type="text"
                value={clipId}
                onChange={(e) => setClipId(e.target.value)}
                placeholder="Enter clip ID (UUID)"
                className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black outline-none ring-0 focus:border-black/20 dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100"
              />
            </div>
            <div className="flex-1">
              <label htmlFor="existingSongId" className="mb-1 block text-sm font-medium text-zinc-700 dark:text-zinc-300">
                Existing Song ID (optional)
              </label>
              <input
                id="existingSongId"
                name="existingSongId"
                type="text"
                value={existingSongId}
                onChange={(e) => setExistingSongId(e.target.value)}
                placeholder="Paste an existing song ID to update"
                className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black outline-none ring-0 focus:border-black/20 dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100"
              />
            </div>
            <button
              type="submit"
              disabled={isImporting}
              className="h-[42px] rounded-md bg-black px-4 text-white transition-opacity disabled:opacity-50 dark:bg-white dark:text-black"
            >
              {isImporting ? "Importing..." : "Import"}
            </button>
          </form>
          {importError && <p className="mt-3 text-sm text-red-600 dark:text-red-400">{importError}</p>}
        </section>

        <section className="rounded-xl border border-black/10 bg-white p-6 shadow-sm dark:border-white/10 dark:bg-black">
          <h2 className="mb-4 text-xl font-semibold text-black dark:text-zinc-50">User Metadata</h2>
          <form onSubmit={handleSaveMetadata} className="flex flex-col gap-4">
            <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
              <div>
                <label htmlFor="avatar" className="mb-1 block text-sm font-medium text-zinc-700 dark:text-zinc-300">Avatar Image</label>
                {currentAvatarURL && (
                  <img src={currentAvatarURL} alt="Current avatar" className="mb-2 h-20 w-20 rounded-full object-cover" />
                )}
                <input
                  id="avatar"
                  name="avatar"
                  type="file"
                  accept="image/*"
                  onChange={(e) => setAvatarFile(e.target.files?.[0] || null)}
                  className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black file:mr-4 file:rounded-md file:border-0 file:bg-zinc-100 file:px-3 file:py-2 file:text-sm file:text-black dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100 dark:file:bg-zinc-800 dark:file:text-zinc-100"
                />
              </div>
              <div>
                <label htmlFor="cover" className="mb-1 block text-sm font-medium text-zinc-700 dark:text-zinc-300">Cover Image</label>
                {currentCoverURL && (
                  <img src={currentCoverURL} alt="Current cover" className="mb-2 h-24 w-full rounded-md object-cover" />
                )}
                <input
                  id="cover"
                  name="cover"
                  type="file"
                  accept="image/*"
                  onChange={(e) => setCoverFile(e.target.files?.[0] || null)}
                  className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black file:mr-4 file:rounded-md file:border-0 file:bg-zinc-100 file:px-3 file:py-2 file:text-sm file:text-black dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100 dark:file:bg-zinc-800 dark:file:text-zinc-100"
                />
              </div>
            </div>

            <div>
              <label htmlFor="bio" className="mb-1 block text-sm font-medium text-zinc-700 dark:text-zinc-300">Bio</label>
              <textarea
                id="bio"
                name="bio"
                value={bio}
                onChange={(e) => setBio(e.target.value)}
                placeholder="Tell us about the user"
                rows={4}
                className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black outline-none ring-0 focus:border-black/20 dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100"
              />
            </div>

            <div>
              <label htmlFor="tags" className="mb-1 block text-sm font-medium text-zinc-700 dark:text-zinc-300">Tags</label>
              <input
                id="tags"
                name="tags"
                type="text"
                value={tags}
                onChange={(e) => setTags(e.target.value)}
                placeholder="e.g. pop, electronic, indie"
                className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black outline-none ring-0 focus:border-black/20 dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100"
              />
            </div>

            <div className="flex items-center gap-3">
              <button
                type="submit"
                disabled={isSavingMeta}
                className="h-[42px] rounded-md bg-black px-4 text-white transition-opacity disabled:opacity-50 dark:bg-white dark:text-black"
              >
                {isSavingMeta ? "Saving..." : "Save Metadata"}
              </button>
              {metaError && <p className="text-sm text-red-600 dark:text-red-400">{metaError}</p>}
            </div>
          </form>
        </section>

        <section className="rounded-xl border border-black/10 bg-white p-6 shadow-sm dark:border-white/10 dark:bg-black">
          <h2 className="mb-4 text-xl font-semibold text-black dark:text-zinc-50">Songs</h2>
          <div className="overflow-x-auto">
            <table className="min-w-full table-auto border-collapse">
              <thead>
                <tr className="text-left text-sm text-zinc-600 dark:text-zinc-300">
                  <th className="border-b border-black/10 px-3 py-2 font-medium dark:border-white/10">Name</th>
                  <th className="border-b border-black/10 px-3 py-2 font-medium dark:border-white/10">Song ID</th>
                  <th className="border-b border-black/10 px-3 py-2 font-medium dark:border-white/10">Actions</th>
                </tr>
              </thead>
              <tbody>
                {songs.map((s) => (
                  <tr key={s.id} className="text-sm text-zinc-800 dark:text-zinc-200">
                    <td className="border-b border-black/5 px-3 py-2 dark:border-white/5">
                      {editingSongId === s.id ? (
                        <input
                          type="text"
                          value={editingSongName}
                          onChange={(e) => setEditingSongName(e.target.value)}
                          placeholder="Enter song name"
                          className="w-full rounded-md border border-black/10 bg-white px-3 py-2 text-black outline-none ring-0 focus:border-black/20 dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100"
                        />
                      ) : (
                        <span>{s.title || s.name || "—"}</span>
                      )}
                    </td>
                    <td className="border-b border-black/5 px-3 py-2 dark:border-white/5">{s.id}</td>
                    <td className="border-b border-black/5 px-3 py-2 dark:border-white/5">
                      {editingSongId === s.id ? (
                        <div className="flex items-center gap-2">
                          <button
                            type="button"
                            disabled={isSavingRename}
                            onClick={saveSongName}
                            className="rounded-md bg-black px-3 py-1 text-white transition-opacity disabled:opacity-50 dark:bg-white dark:text-black"
                          >
                            {isSavingRename ? "Saving..." : "Save"}
                          </button>
                          <button
                            type="button"
                            disabled={isSavingRename}
                            onClick={cancelEditingSong}
                            className="rounded-md border border-black/10 bg-white px-3 py-1 text-black dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100"
                          >
                            Cancel
                          </button>
                          {renameError && (
                            <span className="ml-2 text-xs text-red-600 dark:text-red-400">{renameError}</span>
                          )}
                        </div>
                      ) : (
                        <div className="flex items-center gap-2">
                          <button
                            type="button"
                            onClick={() => startEditingSong(s)}
                            className="rounded-md border border-black/10 bg-white px-3 py-1 text-black hover:bg-zinc-100 dark:border-white/10 dark:bg-zinc-900 dark:text-zinc-100 dark:hover:bg-zinc-800"
                          >
                            Rename
                          </button>
                          <button
                            type="button"
                            onClick={() => handleDeleteSong(s.id)}
                            disabled={deletingSongId === s.id}
                            className="rounded-md bg-red-600 px-3 py-1 text-white transition-opacity disabled:opacity-50"
                          >
                            {deletingSongId === s.id ? "Deleting..." : "Delete"}
                          </button>
                        </div>
                      )}
                    </td>
                  </tr>
                ))}
                {songs.length === 0 && (
                  <tr>
                    <td colSpan={3} className="px-3 py-4 text-center text-sm text-zinc-500 dark:text-zinc-400">
                      No songs found for this user.
                    </td>
                  </tr>
                )}
              </tbody>
            </table>
          </div>
        </section>
      </main>
    </div>
  );
}


